# 给你一个整数数组 nums 和一个整数 k ，编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组：
#  子数组大小 至少为 2 ，且
#  子数组元素总和为 k 的倍数。
#  如果存在，返回 true ；否则，返回 false 。
#  如果存在一个整数 n ，令整数 x 符合 x = n * k ，则称 x 是 k 的一个倍数。0 始终视为 k 的一个倍数。
#
#  示例 1：
# 输入：nums = [23,2,4,6,7], k = 6
# 输出：true
# 解释：[2,4] 是一个大小为 2 的子数组，并且和为 6 。
#
#  示例 2：
# 输入：nums = [23,2,6,4,7], k = 6
# 输出：true
# 解释：[23, 2, 6, 4, 7] 是大小为 5 的子数组，并且和为 42 。
# 42 是 6 的倍数，因为 42 = 7 * 6 且 7 是一个整数。
#
#  示例 3：
# 输入：nums = [23,2,6,4,7], k = 13
# 输出：false
from typing import List


class Solution:
    def checkSubarraySum2(self, nums: List[int], k: int) -> bool:
        """
        如果两个数对k取模相等,那么两数之差一定能被k整除
        如果两个前缀和(prefixSums[i] % k) = (prefixSums[j] % k) ,且 i - j  >= 2
        :param nums:
        :param k:
        :return:
        """
        numLen = len(nums)
        dic = {0: -1}  # key: 对k取模的余数, v:每个余数第一次出现的下标
        tmp = 0  # 前缀和余数临时变量
        for i in range(numLen):
            tmp = (tmp + nums[i]) % k
            if tmp in dic:
                if i - dic[tmp] >= 2:
                    return True
            else:
                dic[tmp] = i
        return False

    def checkSubarraySum1(self, nums: List[int], k: int) -> bool:
        """
        解法一：前缀和(超时)
        prefixSum[i] 表示数组的前 i项和
        则prefixSum[i] - prefixSum[j] = nums[j + 1] + nums[j + 2] + ... + nums[i]
        :param nums:
        :param k:
        :return:
        """
        numLen = len(nums)
        if numLen <= 1:
            return False
        prefixSum = [0] + [0] * numLen
        for i in range(1, numLen + 1):
            prefixSum[i] = prefixSum[i - 1] + nums[i - 1]
        for i in range(1, numLen + 1):
            for j in range(i):
                if i - j > 1 and (prefixSum[i] - prefixSum[j]) % k == 0:
                    return True
        return False

    def checkSubarraySum(self, nums: List[int], k: int) -> bool:
        return self.checkSubarraySum2(nums, k)


if __name__ == "__main__":
    nums, k = [23, 2, 4, 6, 7], 6
    nums, k = [23, 2, 6, 4, 7], 13
    nums, k = [23, 2, 4, 6, 6], 7
    nums, k = [1, 0], 2
    # nums, k = [5, 0, 0, 0], 2
    print(Solution().checkSubarraySum(nums, k))
